<template>
    <!-- 搜索框 -->
    <div class="search">
        <el-select @clear="clearSearchKey" v-model="searchkey" filterable clearable remote reserve-keyword
            placeholder="请输入姓名" :remote-method="remoteMethod" @change="searchChange" :loading="searchloading">
            <el-option v-for="item in searchOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
    </div>
    <!-- 添加按钮 -->
    <el-button type="primary" :icon="Plus" @click="addStu">添加项目</el-button>
    <!-- 导出excel表格 -->
    <el-button @click="exportExcel" class="btn">
        <template #icon>
            <svg>
                <use class="icon" xlink:href="#icon-Excel"></use>
            </svg>
        </template>
        <template #default>
            导出excel表格
        </template>
    </el-button>
    <!-- 表格 -->
    <div class="table">
        <el-table :data="tableData" border v-loading="tableloading">
            <el-table-column label="头像" width="100">
                <template v-slot="{ row }">
                    <!-- <img :src="scope.row.headimgurl" alt="" height="50"> -->
                    <el-avatar size="large" shage="square" :src="row.headimgurl"></el-avatar>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="120" />
            <el-table-column prop="degree" label="学历" />
            <el-table-column prop="class" label="班级" />
            <el-table-column prop="productUrl" label="项目" />
            <el-table-column prop="cTime" label="创建时间" />
            <el-table-column label="操作">
                <template v-slot="{ row }">
                    <el-button v-has:read="permission" :icon="View">查看</el-button>
                    <el-button v-has:edit="permission" :icon="Edit" @click="edit(row)">编辑</el-button>
                    <el-button v-has:delete="permission" type="danger" :icon="Delete" @click="del(row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
    </div>
    <!-- 分页 -->
    <div class="page">
        <el-pagination background layout="prev, pager, next" @current-change="pageChange" :current-page="currentpage"
            :total="total" />
    </div>
    <!-- dialog弹窗 -->
    <qfDialog :dialogFormData="dialogFormData" @closed="close" :visible="dialogVisible" @dialogcancel="dialogcancel"
        @validateSucess="dialogFormValidateSucess" :title="dialogtitle">
        <template v-slot:upload>
            <el-upload class="avatar-uploader" method="post" action="/api/students/uploadStuAvatar"
                v-loading="uploading" :show-file-list="false" name="headimgurl" :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload">
                <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon">
                    <Plus />
                </el-icon>
            </el-upload>
        </template>
    </qfDialog>
</template>
<script setup>
import { ref } from 'vue';
// 引入请求数据的方法
import * as api from "@/api/students"
import { userUser } from "../../../../store/users"
import { storeToRefs } from 'pinia';
import { onMounted } from 'vue';
import { ElMessage, ElMessageBox } from "element-plus"
// 引入图标
import {
    Delete,
    View,
    Edit,
    Plus
} from "@element-plus/icons-vue"

// 引入 dialog
import qfDialog from "@/components/dialog/index.vue"
// 引入导出表格插件
import qee from "qf-export-excel"


// 搜索逻辑
// 搜索关键字
let searchkey = ref('')

let searchloading = ref(false)

// 联想列表的选项
let searchOptions = ref([])

// // 搜索框输入后会触发的方法  负责呈现联想的搜索数据 即选项值
let remoteMethod = async (currentKeyword) => {
    if (!currentKeyword) {
        return
    }
    // 输入的值 currentKeyword
    // 开启 搜索loading
    tableloading.value = true
    searchloading.value = true



    //保证用户在输入或者选择的时候都能获取到搜索关键字 
    // let key = searchkey.value ? searchkey.value : currentKeyword
    try {
        let res = await api.searchStuListApi(currentKeyword)
        // console.log(res);
        // 给联想的列表进行赋值
        let repeatDatas = res.data.data.map(item => ({ value: item.name }))
        // 下拉框值去重
        let norepeatDatas = []
        for (var i = 0; i < repeatDatas.length; i++) {
            let flag = true
            for (var j = 0; j < norepeatDatas.length; j++) {
                if (repeatDatas[i].value === norepeatDatas[j].value) {
                    flag = false
                    break;
                }
            }
            if (flag) {
                norepeatDatas.unshift(repeatDatas[i])
            }
        }
        // console.log(norepeatDatas);
        // 去重后赋值
        searchOptions.value = norepeatDatas
        // 对表格的操作
        tableData.value = res.data.data
        // 关闭 搜索 loading
        searchloading.value = false
        tableloading.value = false
    } catch (e) {
        console.log(e);
        searchloading.value = false
        tableloading.value = false
    }
}




// 列表逻辑
// 表格数据
let tableData = ref([])

let tableloading = ref(true)

// 封装方法，专用于获取表格数据 以便后期调用
let getStulist = async (page, count, classes) => {
    // 请求前 给 loading
    tableloading.value = true
    try {
        let res = await api.getStutentApi(page, count = 10, classes)

        // 给表格赋值
        tableData.value = res.data.data
        // 请求完毕 关闭动画
        tableloading.value = false

        // 设置分页器数量
        setPageNation(res.data.total)
    } catch (e) {
        console.log(e);
        // 出错了也得关闭
        tableloading.value = false
    }
}


// 清空关键字之后的方法
let clearSearchKey = () => {
    // console.log(currentpage.value);
    // 初始化数据让页码重新回到第一页
    currentpage.value = 1
}

// 用户选择了输入框的值后  负责更新表格数据
let searchChange = async (key, page = 1, count = 10) => {
    // 开启loading
    tableloading.value = true
    // 获取用户选择的值
    // console.log(searchkey.value);

    // 需要清掉 搜索选项
    searchOptions.value = []
    try {
        let res = await api.searchStuListApi(searchkey.value, count, page)

        // 对表格数据的操作
        tableData = res.data.data
        // 关闭 loading
        tableloading.value = false
        // 对搜索的结果进行分页
        setPageNation(res.data.total)
    } catch (e) {
        console.log(e);
        tableloading.value = false
    }
}

// 处理分页器
// 当前的页码
// 分页器的total属性，也就是总值
let total = ref(1)
// 一页展示多少条
let pageSize = ref(10)
// 默认页码
let currentpage = ref(1)
// 页码变更的时候
let pageChange = (inputCurrentPage) => {
    // console.log(current);
    // 动态变更页码
    currentpage.value = inputCurrentPage
    // 判断有没有关键字，如果有就更新搜索分页结果
    if (searchkey.value) {
        searchChange(null, inputCurrentPage)
    } else {
        // 然后 重新拉取列表内容
        getStulist(inputCurrentPage)
    }

}

// 专门修改分页器内容的方法
let setPageNation = (totalCount = 10, count = 10, currentPage = 1) => {
    total.value = totalCount
    pageSize.value = count
}

// 添加stu信息
// 声明 dialogFormVisible 控制dialog
// dialog标题
let dialogtitle = ref('增加学员信息')
let dialogVisible = ref(false)
let addStu = () => {
    // 打开 dialog
    dialogVisible.value = true
    dialogtitle.value = "增加学员信息"
}

// dialog数据源
let dialogFormData = ref({
    name: {
        label: "姓名",
        value: ""
    },
    class: {
        label: "班级",
        value: ""
    },
    productUrl: {
        label: "项目地址",
        value: ""
    },
    age: {
        label: "年龄",
        value: ""
    },
    city: {
        label: "城市",
        value: ""
    },
    degree: {
        label: "学历",
        value: ""
    },
    description: {
        label: "描述",
        value: ""
    }
})

// dialog 确定按钮被动点击 且通过校验
let dialogFormValidateSucess = async (form) => {
    // console.log(form);
    // 点击确定发起请求添信息
    // 声明变量控制弹窗提示
    let message = "添加成功"
    let params = {
        headimgurl: "",
        class: dialogFormData.value.class.value,
        name: dialogFormData.value.name.value,
        age: dialogFormData.value.age.value,
        city: dialogFormData.value.city.value,
        degree: dialogFormData.value.degree.value,
        description: dialogFormData.value.description.value,
        productUrl: dialogFormData.value.productUrl.value
    }
    try {
        let apiMenthod = ref(null)

        switch (dialogtitle.value) {
            case "增加学员信息":
                apiMenthod = api.addStuApi
                // 在增加时删除sId属性
                params.sId ? delete params.sId : ""
                break
            case "编辑学员信息":
                apiMenthod = api.updateStuApi;
                // 添加 sId
                params.sId = sId.value
                // 到编辑里就改消息提示
                message = "修改成功"
        }
        // 判断是否上传头像，如果上传，那就携带到params里
        params.headimgurl = headimgurl.value ? headimgurl.value : ''
        let res = await apiMenthod(params)
        console.log(res)
        // 根据dialogtitle区别发送的哪个请求
        // 添加成功
        // 1.提示添加成功
        ElMessage({
            type: "success",
            message
        })
        // 2.关掉dialog
        dialogVisible.value = false
        // 3.清空表单
        form.value.resetFields()
        // 4.更新列表
        getStulist()

    } catch (e) {
        ElMessage({
            type: "error",
            message: e.toString()
        })
        console.log(e);
    }
}

// 点击 dialog 取消按钮触发的逻辑
let dialogcancel = () => {
    console.log('取消成功');
    dialogVisible.value = false
}

// dialog关闭之后要同步控制关闭属性的值
// 为了处理点击空白区域或叉掉的时候造成后续dialog不能弹出
let close = () => {
    dialogVisible.value = false
    // console.log(dialogVisible.value);
    // 将数据清空
    let keys = Object.keys(dialogFormData.value)
    keys.forEach(key => {
        // console.log(key);
        dialogFormData.value[key].value = ""
    })
    // 清空头像的回显
    imageUrl.value = ''
}

// 编辑
// 声明一个变量存储sId，便于编辑的时候传递给后端
let sId = ref('')
let edit = (row) => {
    //1. 打开 dialog
    dialogVisible.value = true
    // 2.修改标题
    dialogtitle.value = "编辑学员信息"
    console.log(row);
    // 2.数据回显;
    let keys = Object.keys(dialogFormData.value)
    // console.log(keys);
    keys.forEach(key => {
        // console.log(key);
        dialogFormData.value[key].value = row[key]
    })
    // 给sId 赋值
    sId.value = row.sId
    // 更改全局headimgurl 便于数据的回显和传递
    headimgurl.value = row.headimgurl
    // 回显
    imageUrl.value = row.headimgurl
}

// 删除
let del = (row) => {
    console.log(row);
    // 获取当前数据的id，传递给后台
    // 1.交互，让用户确认是否删除
    ElMessageBox.confirm("是否删除" + row.name + '?', 'Error', {

        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: 'warning',

    })
        .then(async () => {
            // 发请求删除
            try {
                let res = await api.delStuApi(row.sId)
                ElMessage({
                    type: "success",
                    message: "删除成功"
                })
                // 更新列表
                getStulist()

            } catch (e) {
                console.log(e);
                ElMessage({
                    type: "error",
                    message: e.toString()
                })
            }

        })
        .catch(() => {
            // 取消删除
            ElMessage({
                type: "warning",
                message: "已取消删除"
            })
        })

}

// 声明加载动画
let uploading = ref(false)
// 上传文件
let imageUrl = ref()
// 声明一个headimgurl变量用于将参数在表单dialog通过的时候一并提交给后台
let headimgurl = ref()
// 上传成功的方法
let handleAvatarSuccess = (res, uploadFile) => {
    // console.log(res);
    if (res.state) {
        // 头像上传成功
        ElMessage({
            type: "success",
            message: res.msg
        })
        headimgurl.value = res.headimgurl
    } else {
        ElMessage({
            type: "error",
            message: res.msg
        })
    }
    // 关闭加载动画 
    uploading.value = false
    imageUrl.value = URL.createObjectURL(uploadFile.raw)
}


// 上传之前
let beforeAvatarUpload = (rawFile) => {
    // 限制格式
    // 允许上传的文件类型
    let acceptType = ['image/jpeg', 'image/png']
    console.log(rawFile.type);
    // 判断上传的文件类型是否包含在数组中
    let isAccept = acceptType.includes(rawFile.type)
    if (!isAccept) {
        ElMessage.error('上传的文件类型，只能是jpeg或png')
        return false
        // 限制大小
    } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('上传的图片不能大于1M')
        return false
    }
    // 打开加载动画
    uploading.value = true
    return true
}

onMounted(() => {
    getStulist()
})

// 从 pinia 里那按钮权限
let useStore = userUser()

let { permission } = storeToRefs(useStore)
// 按钮鉴权
let vHas = {
    mounted(el, binding) {
        //    console.log(permission.value.buttons,"用户");
        //    console.log(binding.arg,"按钮权限");

        let useRole = permission.value.buttons
        //    console.log(useRole);
        let roule = binding.arg
        //    console.log(roule);
        let hasRole = useRole.includes(roule)
        // console.log(hasRole);
        if (!hasRole) {
            el.parentNode.removeChild(el)
        }
    }
}

// 导出excel
let exportExcel = () => {
    // 定义表头
    let titleSource = [
        {
            title:"姓名",
            key:"name"
        },
        {
            title:"年龄",
            key:"age"
        },
        {
            title:"头像地址",
            key:"headimgUrl"
        },
        {
            title:"学历",
            key:"degree"
        },
        {
            title:"班级",
            key:"class"
        }
  ]
    // qee(titleList,dataSource,fileName)
    qee(titleSource,tableData.value,"后台管理系统数据")
}




</script>
<script>
export default {
    meta: { title: 'xyxmgl', name: '学员项目管理', routeName: "stuProduct", icon: "#icon-xueyuan1" }
}
</script>

<style lang="less" scoped>
body {
    position: relative;
}

.btn {
    position: absolute;
    right: 50px;
}

.search {
    width: 500px;
    height: 60px;
    margin: 20px;

    :deep(.el-input__wrapper) {
        width: 300px !important;
        height: 40px !important;
    }
}

.table {
    :deep(.el-table .el-table__cell) {
        text-align: center;
    }
}

.page {
    width: 500px;
    height: 50px;
    // border: 1px solid;
    margin: auto;
    position: relative;
    top: 16px;
}
</style>